/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package it.polimi.meteocal.boundary;

import it.polimi.meteocal.control.EventManager;
import it.polimi.meteocal.control.UserManager;
import it.polimi.meteocal.entity.Event;
import it.polimi.meteocal.entity.InvitedList;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;

import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.inject.Named;

/**
 *
 * @author paolo
 */
@Named(value = "eventBean")
@ViewScoped
public class EventBean implements Serializable {

    private Event event;
    private int type;
    private String typeString;
    private Date beginDate;
    private Date endDate;
    private String invitedUser;
    private ArrayList<String> invitedUsers;
    private ArrayList<InvitedList> invList;
    private String selectedid;

    @EJB
    private EventManager em;
    @EJB
    private UserManager um;

    public EventBean() {
    }

    public ArrayList<InvitedList> getInvList() {
        return invList;
    }

    public void setInvList(ArrayList<InvitedList> invList) {
        this.invList = invList;
    }

    public String getSelectedid() {
        return selectedid;
    }

    public void setSelectedid(String selectedid) {
        this.selectedid = selectedid;
    }

    public String getInvitedUser() {
        if (invitedUser == null) {
            invitedUser = "";
        }
        return invitedUser;
    }

    public void setInvitedUser(String invitedUser) {
        this.invitedUser = invitedUser;
    }

    public String getTypeString() {
        return typeString;
    }

    public void setTypeString(String typeString) {
        this.typeString = typeString;
    }

    public ArrayList<String> getInvitedUsers() {
        if (invitedUsers == null) {
            invitedUsers = new ArrayList<>();
        }
        return invitedUsers;
    }

    public void setInvitedUsers(ArrayList<String> invitedUsers) {
        this.invitedUsers = invitedUsers;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public Event getEvent() {
        if (event == null) {
            event = new Event();
        }
        return event;
    }

    public void setEvent(Event event) {
        this.event = event;
    }

    public Date getBeginDate() {
        return beginDate;
    }

    public void setBeginDate(Date beginDate) {
        this.beginDate = beginDate;
    }

    public Date getEndDate() {
        return endDate;
    }

    public void setEndDate(Date endDate) {
        this.endDate = endDate;
    }

    public void addUser(String invitedUser) {
        invitedUsers.add(invitedUser);
    }

    /**
     * setting of all the field of the event calling the database
     *
     * @return homePage of the logged user
     */
    public String save() {
        System.out.println("**************SAVE*************");
        switch (type) {
            case 1:
                event.setPublicEvent(Boolean.TRUE);
                event.setOutdoor(Boolean.FALSE);
                break;
            case 2:
                event.setPublicEvent(Boolean.TRUE);
                event.setOutdoor(Boolean.TRUE);
                break;
            case 3:
                event.setPublicEvent(Boolean.FALSE);
                event.setOutdoor(Boolean.FALSE);
                break;
            case 4:
                event.setPublicEvent(Boolean.FALSE);
                event.setOutdoor(Boolean.TRUE);
                break;

        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(endDate);
        event.setEndHour((GregorianCalendar) cal);
        event.setEndDate((GregorianCalendar) cal);
        Calendar calo = Calendar.getInstance();
        calo.setTime(beginDate);
        event.setStartDate((GregorianCalendar) calo);
        event.setStartHour((GregorianCalendar) calo);
        em.createEvent(event, invitedUsers);
        //cleaning input form
        event = new Event();
        if (!invitedUsers.isEmpty()) {
            invitedUsers.clear();
        }
        invitedUser = "";
        type = 69;
        beginDate = null;
        endDate = null;
        return "homepage?faces-redirect=true";
    }

    /**
     * check if the user to invite is alredy invited, is the author or isn't
     * registered to the system adding an error message
     *
     * @return nothing only to keep alive the bean
     */
    public String checkUser() {
        System.out.println("**************CHECKUSER*************" + invitedUser);
        if (um.checkExistUser(invitedUser) && !um.getLoggedUser().getEmail().equals(invitedUser)
                && !invitedUsers.contains(invitedUser)) {
            invitedUsers.add(invitedUser);
            invitedUser = "";
        } else {
            System.out.println("can't add this");
            FacesContext ctx = FacesContext.getCurrentInstance();
            ctx.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Can't add this", null));
        }
        return "";
    }

    /**
     * clear the invited list user when abort the action
     *
     * @return homePage
     */
    public String abort() {
        System.out.println("**************ABORT*************");
        if (!invitedUsers.isEmpty()) {
            invitedUsers.clear();
        }
        invitedUser = "";
        return "homepage";
    }

    /**
     * inizialize the event detail for the event detail page hiding them if the
     * event is private and the logged user isn't the creator or invited to the
     * event. disable the button modify and delete if the logged user isn't the
     * authore of the event
     */
    public void init() {
        System.out.println("************LOADING EVENT********** " + selectedid);
        event = em.findByID(selectedid);
        if (!event.getPublicEvent() && !um.getLoggedUser().getEmail().equals(event.getAuthor().getEmail())
                && !em.invited(selectedid)) {
            event.getAuthor().setName("****");
            event.getAuthor().setSurname("");
            event.setName("****");
            event.setDescription("****");
            typeString = "PRIVATE";
            event.setCity("****");
            event.setCountry("****");
            event.setAddress("****");
            invitedUsers = new ArrayList<>();
            invitedUsers.add("****");
            invList = new ArrayList<>();
            invList.clear();
        } else {
            if (event.getOutdoor() && event.getPublicEvent()) {
                typeString = "Public Outdoor";
            }
            if (!event.getOutdoor() && !event.getPublicEvent()) {
                typeString = "Private Indoor";
            }
            if (!event.getOutdoor() && event.getPublicEvent()) {
                typeString = "Public Indoor";
            }
            if (event.getOutdoor() && !event.getPublicEvent()) {
                typeString = "Private Outdoor";
            }

            invitedUsers = new ArrayList<>();
            Collection<InvitedList> invitedListCollection = event.getInvitedListCollection();
            String s;
            invList = new ArrayList<>();
            for (InvitedList invitedList : invitedListCollection) {
                s = invitedList.getUser().getEmail();
                invList.add(invitedList);
                if (invitedList.getPartecipation() == null) {
                    s = s + ". The user has not answered yet. \n";
                } else {
                    if (invitedList.getPartecipation()) {
                        s = s + ". The user has already said that he/she will participate to the event. \n";
                    } else {
                        s = s + ". The user has already said that he/she will not participate to the event. \n";
                    }
                }
                invitedUsers.add(s);
            }
        }
        GregorianCalendar cal = event.getEndDate();
        cal.set(Calendar.HOUR_OF_DAY, event.getEndHour().get(Calendar.HOUR_OF_DAY));
        cal.set(Calendar.MINUTE, event.getEndHour().get(Calendar.MINUTE));
        endDate = cal.getTime();
        cal = event.getStartDate();
        cal.set(Calendar.HOUR_OF_DAY, event.getStartHour().get(Calendar.HOUR_OF_DAY));
        cal.set(Calendar.MINUTE, event.getStartHour().get(Calendar.MINUTE));
        beginDate = event.getStartDate().getTime();
    }

    /**
     *
     * @return the mofification page according to the event visualized
     */
    public String gotoModify() {
        System.out.println("*******MODIFY*****");
        return ("eventmodification?faces-redirect=true&idevent=" + selectedid);
    }

    /**
     * call the data base to make modify
     *
     * @return homePage
     */
    public String delete() {
        em.delete(event);
        return "homepage";
    }

    /**
     * check
     *
     * @return false if the logged user is the author of the event, true
     * otherwise
     */
    public boolean checkPrivilege() {
        return !event.getAuthor().getEmail().equals(um.getLoggedUser().getEmail());
    }

    /**
     *
     * @return textual rappresentation of teh forecast identifier
     */
    public String getForecastText() {
        if (event.getForecast() == null) {
            return "no weather forecast available";
        }
        if (!event.getPublicEvent() && !um.getLoggedUser().getEmail().equals(event.getAuthor().getEmail())
                && !em.invited(selectedid)) {
            return "****";
        } else {
            return (WeatherConverter.getText(event.getForecast().getForecast()));
        }
    }

    public Date getToday() {
        return new Date();
    }

    public String getIcon() {
        if (event.getForecast() == null || event.getForecast().getForecast() == 0 || getForecastText().equals("****")) {
            return "/images/NoForecast_icon.png";
        } else {
            return (WeatherConverter.getImage(event.getForecast().getForecast(), event.getStartHour()));
        }
    }

    public EventManager getEm() {
        return em;
    }

    public void setEm(EventManager em) {
        this.em = em;
    }

    public UserManager getUm() {
        return um;
    }

    public void setUm(UserManager um) {
        this.um = um;
    }
}
